﻿#pragma once
#include <list>
#include "MObject.h"
#include <set>
#include "Collision.h"
#include <memory>

class QuadNode
{
public:
	QuadNode(float x, float y, int width, int height);
	~QuadNode(void);

	void AddObject(shared_ptr<MObject> object,int Height);
	int CheckRect(RECT rect);
	std::list<shared_ptr<MObject>> getObjectList();
	std::list<shared_ptr<MObject>> getMovingObjectList(const RECT &rect, bool remove);
	void setObjectList(const std::list<shared_ptr<MObject>> &newList);
	std::list<shared_ptr<MObject>> getAllObjectList();
	QuadNode* getNode(const RECT &rect);
	std::list<shared_ptr<MObject>> getCollidableObject(const RECT &rect);
	std::list<shared_ptr<MObject>> getMovableObjects(const RECT &rect, bool remove);
	bool isIntersect(RECT rect1, RECT rect2);
	bool isBelong(shared_ptr<MObject> object);

	RECT getRect(){return _nodeRect;};
	RECT getLooseRect(){return _looseRect;};

	QuadNode** getNodeList();

	bool isDivided();

	RECT calChildRect(int childIndex);

	void free();

	int countObject();


protected:
	RECT _nodeRect,_looseRect;
	int _maxHeight;

	QuadNode **_nodeList;
	std::list<shared_ptr<MObject>> _objectList;
	std::list<shared_ptr<MObject>> _deletedObjectList;



	bool _isDivided;

	const static int TL = 1;	//TOP LEFT
	const static int TR = 2;	//TOP RIGHT
	const static int BR = 3;	//BOTTOM RIGHT
	const static int BL = 4;	//BOTTOM LEFT
};

class QuadTree
{
protected:
	QuadNode* _root;
	Collision _coll;
	int _width,_height;

public:
	QuadTree(void);
	QuadTree(int width, int height);
	~QuadTree(void);

	void add(shared_ptr<MObject> obj);
	QuadNode* getRoot(){ return this->_root;};

	std::list<shared_ptr<MObject>> checkCollision(QuadNode *currentNode, const RECT &rect); // duyệt cây,xử lý va chạm, trả về danh sách các obj cần cập nhật lại vị trí trên cây

	Vector getSize(){return Vector(_width,_height);};
};